package com.sz.contro;

import com.alibaba.fastjson.JSONObject;
import com.sz.entity.Users;
import com.sz.service.UsersService;
import com.sz.service.SmsApiService;
import com.sz.util.AesCryptUtil;
import com.sz.util.RsaCryptUtil;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

@Controller
@RequestMapping("/uc")
public class UsersContro {
    @Resource
    private UsersService usersService;

    @Resource
    private RedisTemplate<String,String> redisTemplate;

    @Resource
    private RsaCryptUtil rsaCryptUtil;

    @Resource
    private AesCryptUtil aesCryptUtil;

    @Resource
    private PasswordEncoder passwordEncoder;

    @Resource
    private SmsApiService smsApiService;

    @RequestMapping(value = "index")
    public String findindex(){
        return "success";
    }

    /**
     * 账号密码登录,在前端加密过的密码进行解密后,再与数据库的数据进行配对
     * @param users 前端穿过的账号,加密过后的密码
     * @param key RSA加密后的AES秘钥
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "sign_acount",method = RequestMethod.POST)
    public String findUserByNamePwd(Users users, String key , HttpServletRequest request) throws Exception {
        //对RSA加密后的AES秘钥进行解密,得到AES秘钥
        String aeskey = rsaCryptUtil.rsaDescryptRandKey(key,rsaCryptUtil.getPrivateRSAKey());
        //用得到的AES秘钥对加密过后的密码进行解密,得到pwd
        String pwd = aesCryptUtil.encrypt(users.getUserpwd(),aeskey,aeskey);
        users.setUserpwd(pwd);
        //判断us是否为空
        Users us = usersService.getUsersByNamePwd(users);
        if(us == null){
            return "login";
        }
        //用解密过后的密码pwd与数据库进行比对
        boolean flag = passwordEncoder.matches(users.getUserpwd(),us.getUserpwd());
        if((us == null && flag == false) || (us != null && flag == false)){
            return "login";
        }
        HttpSession session = request.getSession();
        String sessionid = UUID.randomUUID().toString();
        session.setAttribute("sessionid",sessionid);
        //得到用户的id
        String id = String.valueOf(us.getUserid());
        //用户信息序列化
        String userstr = JSONObject.toJSONString(us);
        //把序列化后的json数据存入redis,key为用户id,过期时间设置为10分钟
        redisTemplate.opsForValue().set(id,userstr,10, TimeUnit.MINUTES);
        //根据id从redis取出用户信息
        String name = redisTemplate.opsForValue().get(id);
        return "redirect:index";
    }
    @GetMapping(value = "sign_acount")
    public String findUserByNamePwd(HttpServletRequest request){
        HttpSession session = request.getSession();
        String sessionid = (String) session.getAttribute("sessionid");
        System.out.println("sessionid : "+sessionid);
        if(sessionid != null){
            return "index";
        }
        return "login";
    }

    /**
     * 前端发起$ajax请求,后台返回生成的RSA公钥
     * @return
     */
    @RequestMapping(value = "pubkey",method = RequestMethod.POST)
    @ResponseBody
    public String findPublicRSAkey(){
        return rsaCryptUtil.getPublicRSAKey();
    }

    /**
     * 手机号验证码登录
     * @param users
     * @param code 验证码
     * @return
     */
    @RequestMapping(value = "signin_phone" ,method = RequestMethod.POST)
    public String findUsersByPhone(Users users,String code){
        //根据手机号从redis里面取短信验证码
        String co = redisTemplate.opsForValue().get(users.getPhone());
        Users us = usersService.getUsersByPhone(users);
        if((us == null && code.equals(co) == false) || (us != null && code.equals(co) == false) || (us == null && code.equals(co) == true)){
            return "login_phone";
        }
        System.out.println(us);
        return "redirect:index";
    }
    @GetMapping(value = "signin_phone")
    public String findUsersByPhone(){
        return "login";
    }

    /*@RequestMapping(value = "sendcode" ,method = RequestMethod.POST)
    @ResponseBody
    public void fin(String phone){
        System.out.println("phone : "+phone);
        String code = redisTemplate.opsForValue().get(phone);
        //生成随机验证码
        code = String.valueOf((Math.random() * 9 + 1 ) * 100000).substring(0,6);
        System.out.println("code : "+code);
        redisTemplate.opsForValue().set(phone,code,5, TimeUnit.MINUTES);
    }*/

   @RequestMapping(value = "sendcode",method = RequestMethod.POST)
   @ResponseBody
   public String findSendCode(String phone){
       String code = String.valueOf((Math.random() * 9 + 1 ) * 100000).substring(0,6);
       Map<String,Object> param = new HashMap<String,Object>();
       param.put("code",code);
       boolean isSend = smsApiService.sendSmsCode(phone,"星河说","SMS_194910148",param);
       if(isSend==true){
           redisTemplate.opsForValue().set(phone,code,5, TimeUnit.MINUTES);
           return "发送成功!";
       }else {
           return "发送失败!";
       }
   }

    /**
     * 账户注册
     * @return
     */
    @RequestMapping(value = "user_add" ,method = RequestMethod.GET)
    public String findAddUsers(){
        return "register";
    }

    @RequestMapping(value = "user_add" ,method = RequestMethod.POST)
    public String findAddUsers(Users users,String key) throws Exception {
        //对RSA加密后的AES秘钥进行解密,得到AES秘钥
        String aeskey = rsaCryptUtil.rsaDescryptRandKey(key,rsaCryptUtil.getPrivateRSAKey());
        //用得到的AES秘钥对加密过后的密码进行解密,得到pwd
        //String pwd = aesCryptUtil.encrypt(users.getUserpwd(),aeskey,aeskey);
        //对得到密码pwd进行后台加密
        String userpwd = passwordEncoder.encode(aesCryptUtil.encrypt(users.getUserpwd(),aeskey,aeskey));
        users.setUserpwd(userpwd);
        int count = usersService.getAddUsers(users);
        if(count<=0){
            return "register";
        }
        return "redirect:sign_acount";
    }

    /**
     * 验证用户名是否存在
     * @param username
     * @return
     */
    @PostMapping(value = "checkusername")
    @ResponseBody
    public int findCheckUserName(String username){
        int count = usersService.getCheckUserName(username);
        return count;
    }

    /**
     * 验证手机号唯一
     * @param phone
     * @return
     */
    @PostMapping(value = "checkuserphone")
    @ResponseBody
    public int findCheckUserPhone(String phone){
        int count2 = usersService.getCheckUserPhone(phone);
        return count2;
    }

}
